package com.tanhua.dubbo.api;

import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.tanhua.domain.db.PageResult;
import com.tanhua.domain.mg.*;
import com.tanhua.domain.vo.MoreDataVo;
import com.tanhua.domain.vo.PublishVo;
import javafx.scene.shape.Circle;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.config.annotation.Service;
import org.bson.types.ObjectId;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;

import java.util.*;

@Service
@Slf4j
public class PublishApiServiceImpl implements PublishApi {

    //注入mogoTempalte对象
    @Autowired
    private MongoTemplate mongoTemplate;

    /**
     * 发布动态
     * @param publishVo
     */
    @Override
    public String publishData(PublishVo publishVo) {
        //1,往发布表插入数据
        //1.0 创建一个共享的时间对象
        long timeMillis = System.currentTimeMillis();
        //1.1 创建一个Publish对象
        Publish publish = new Publish();
        //1.2 将vo对象上的属性复制到publish
        BeanUtils.copyProperties(publishVo,publish);
        //1.3 补全信息
        publish.setId(ObjectId.get());//设置发布的id
        publish.setPid(10L);//默认值 随便写
        publish.setSeeType(1);//1表示可公开
        publish.setLocationName(publishVo.getLocation());//图片地址
        publish.setCreated(timeMillis);
        publish.setUserId(publishVo.getId());
        publish.setMedias(publishVo.getImages());
        //1.4 调用mongoTemplate的api 插入数据
        mongoTemplate.save(publish);
        log.debug("发布表插入数据成功！————————————————————————");
        //2,往相册表插入数据
        Album album = new Album();
        //2.1 注入主键id
        album.setId(ObjectId.get());
        album.setPublishId(publish.getId());//注入发布id
        album.setCreated(timeMillis);//创建时间
        //2.3 调用mongoTemplate方法 插入数据 （指定一个表名 表名的后缀为用户id）
        mongoTemplate.save(album,"quanzi_album_"+publish.getUserId());
       //3.1 创建一个Query 条件为"userId"(当前用户id)
        Query query = Query.query(Criteria.where("userId").is(publish.getUserId()));
        //3.2 调用mongoTemplate方法 查询出符合条件的对象集合
        List<Friend> friends = mongoTemplate.find(query, Friend.class);
        //4,根据ids插入时间线表
        for (Friend friend : friends) {
            TimeLine timeLine = new TimeLine();
            timeLine.setId(ObjectId.get());//主键id
            timeLine.setUserId(publish.getUserId());//用户id
            timeLine.setPublishId(publish.getId());//发布id
            timeLine.setCreated(timeMillis);
            mongoTemplate.save(timeLine,"quanzi_time_line_"+friend.getFriendId());
        }
        return publish.getId().toString();
    }

    /**
     * 好友动态
     * @param currentId
     * @return
     */
    @Override
    public PageResult<Publish> queryPublishById(Long currentId,Integer page,Integer pagesize) {

        //1.定义一个分页的的条件
        Query query = new Query().limit(pagesize).skip((page - 1) * pagesize);
        //2.调用mongoTemplate 传入Query参数 和 表名 返回一个Page<TimeLine>
        List<TimeLine> timeLineList = mongoTemplate.find(query, TimeLine.class, "quanzi_time_line_" + currentId);
        //——————————debug:没有查询到总记录数
        long count = mongoTemplate.count(query, TimeLine.class, "quanzi_time_line_" + currentId);
        //4.创建一个List<Publish>对象
        ArrayList<Publish> pubList = new ArrayList<>();
        //遍历publishList
        for (TimeLine timeLine : timeLineList) {
            //6.根据发布id查询发布表 获得Publish
            ObjectId publishId = timeLine.getPublishId();
            Publish publish = mongoTemplate.findById(publishId, Publish.class);
            //7.将publish对象 存储到List<publish>集合
            if(publish!=null){
                pubList.add(publish);
            }
            }
//      返回分页数据
        return getPublishPageResult(page, pagesize, count, pubList);
    }

    /**
     * 推荐动态
     * @param currentId
     * @param page
     * @param pagesize
     * @return
     */
    @Override
    public PageResult<Publish> queryPublishById2(Long currentId, Integer page, Integer pagesize) {
        //根据用户id和分页条件查询推荐表的指定记录 返回list<RecommendQuanZi>
        Query query = new Query(Criteria.where("userId").is(currentId)).limit(pagesize).skip((page - 1) * pagesize);
        List<RecommendQuanZi> recommendList = mongoTemplate.find(query, RecommendQuanZi.class);

        //如果查询到的集合为null 那么就默认从动态表查询随机的动态展示给用户
        if(CollectionUtils.isEmpty(recommendList)){
          recommendList = getDefaultRecommendIfContextNull();
        }
        //创建一个集合 存储Publish
        ArrayList<Publish> pubList = new ArrayList<>();
        //如果不为null 遍历这个集合
        for (RecommendQuanZi recommendQuanZi : recommendList) {
            //6.根据发布id查询发布表 获得Publish
            ObjectId publishId = recommendQuanZi.getPublishId();
            //判断recommendQuanZi对象的publishId是否为null
            if(ObjectUtils.isNotEmpty(recommendQuanZi.getPublishId())){
                Publish publish = mongoTemplate.findById(publishId, Publish.class);
                //7.将publish对象 存储到List<publish>集合
                if(publish!=null){
                    pubList.add(publish);
                }
            }
        }
        //查询总记录数
        long count = mongoTemplate.count(query, RecommendQuanZi.class);
        if(count==0){
            count=1;
        }
        //返回分页数据
        return getPublishPageResult(page, pagesize, count, pubList);
    }

    /**
     * 我的动态
     */
    @Override
    public PageResult<Publish> MyPublishData(Long currentId, Integer page, Integer pagesize) {
        //1.定义一个分页的的条件
        Query query = new Query().limit(pagesize).skip((page - 1) * pagesize);
        //2.调用mongoTemplate 传入Query参数 和 表名 返回一个Page<Publish>
        List<Album> albumList = mongoTemplate.find(query, Album.class, "quanzi_album_" + currentId);
        //3.创建一个集合  存储MoreDataVo对象
        ArrayList<Publish> pubList = new ArrayList<>();
        //4.遍历albums
        for (Album album : albumList) {
            //4.1 根据albums的发布id 查询发布表
            //获取到发布id
            ObjectId publishId = album.getPublishId();
            //根据发布id 查询发布表
            Query queryPublish = new Query(Criteria.where("_id").is(publishId));
            Publish publish = mongoTemplate.findOne(queryPublish, Publish.class);
            if (ObjectUtils.isEmpty(publish)){
                //如果没有查询到记录 那么就跳出这次循环 进入下次循环
                continue;
            }
            //4.4 添加集合到MoredataVoList
            pubList.add(publish);
        }
        //查询总记录数
        long count = mongoTemplate.count(query, "quanzi_album_" + currentId);
        if(count==0){
            count=1;
        }
        //返回分页数据
        return getPublishPageResult(page, pagesize, count,pubList);
    }

    /**
     * 查询单条动态
     */
    @Override
    public Publish findPublishById(String id) {
        ObjectId objectId = new ObjectId(id);
        Query query = new Query(Criteria.where("_id").is(objectId));
        return mongoTemplate.findOne(query, Publish.class);

    }
    /**
     * 根据发布id和状态修改发布动态表
     * @param message
     * @param state
     */
    @Override
    public void updateStateById(String message, Integer state) {
        ObjectId objectId = new ObjectId(message);
        //创建条件
        Query query = new Query();
        query.addCriteria(Criteria.where("_id").is(objectId));
        //修改的数据
        Update update = new Update();
        update.set("state",state);
        mongoTemplate.updateFirst(query,update,Publish.class);
    }

    /**
     * 根据用户Id查询自己的动态信息
     */
    @Override
    public PageResult<Publish> queryPublishByUserId(Long userId, Integer page, Integer pagesize) {
        //设置分页条件
        Query query = new Query();
        //判断userId是否为null
        if(userId!=null){
            query.addCriteria(Criteria.where("userId").is(userId));
        }
        //调用mongotemplate查询
        List<Publish> publishList = mongoTemplate.find(query, Publish.class);
        //根据查询条件查询总记录数
        long count = mongoTemplate.count(query, Publish.class);
        //调用公共方法
        return getPublishPageResult(page, pagesize, count,publishList);
    }

    /**
     * 传入当前页、每页记录数、总记录数和分页数据可以返回pageResult
     * @param page
     * @param pagesize
     * @param count
     * @param pubList
     * @return
     */
    private PageResult<Publish> getPublishPageResult(Integer page, Integer pagesize, long count, List<Publish> pubList) {
        //查询总页数
        long pages = (count / pagesize) + (count % pagesize > 0 ? 1 : 0);
        //8.封装PageResult
        PageResult<Publish> publishPageResult = new PageResult<>();
        publishPageResult.setItems(pubList);
        publishPageResult.setPage(page);
        publishPageResult.setPagesize(pagesize);
        publishPageResult.setCounts((int)count);
        publishPageResult.setPages((int)pages);
        return publishPageResult;
    }

    /**
     * 推荐用户随机动态
     */
    public List<RecommendQuanZi> getDefaultRecommendIfContextNull() {
        //创建一个集合 存储动态内容
        List<ObjectId> lists=new ArrayList<>();
        Collections.addAll(lists,
                new ObjectId("611b2a7bc710142cf02de891"),
                new ObjectId("611b2b2cc710142cf02de895"),
                new ObjectId("611b2f5bc710142cf02de899"),
                new ObjectId("611b28cdc710142cf02de88b"),
                new ObjectId("611a8473c7101411f8463e81"),
                new ObjectId("611a8d5fc7101411f8463e89"),
                new ObjectId("611b28fcc710142cf02de88d"),
                new ObjectId("611b2bdac710142cf02de897")
                );
        //每次调用都颠倒一下顺序
        Collections.shuffle(lists);
        //遍历集合 查询数据封装成List<RecommendQuanZi>
        List<RecommendQuanZi> list=new ArrayList<>();
        for (int i = 0; i < 5; i++) {
            RecommendQuanZi recommendQuanZi = new RecommendQuanZi();
            ObjectId objectId = lists.get(i);
            //设置发布id
            recommendQuanZi.setPublishId(objectId);
            //添加集合
            list.add(recommendQuanZi);
        }
        //返回
        return list;
    }

}
